<?php
/**
 * Filter.php	
 *
 * @package		
 * @Copyright	(c) All rights reserved
 * @Author		skyCrack <skyCrack@126.com>
 * @Version		$Id$
 */

class Filter
{
	public static function getAlpha($value) {
		return preg_replace('/[^[:alpha:]]/', '', $value);
	}
	
	public static function getAlnum($value) {
		return preg_replace('/[^[:alnum:]]/', '', $value);
	}
	
	public static function getDigits($value) {
		return preg_replace('/[^\d]/', '', $value);
	}
	
	public static function getDir($value) {
		return dirname($value);
	}
	
	public static function getInt($value) {
		return (int) $value;
	}
	
	public static function getPath($value) {
		return realpath($value);
	}
		
	public static function isAlnum($value) {
		return ctype_alnum($value);
	}
	
	public static function isAlpha($value) {
		return ctype_alpha($value);
	}
	
	public static function isBetween($value, $min, $max, $inc = TRUE) {
		if ( ($value > $min) && ($value < $max) ) {
			return TRUE;
		}
		
		if ( ($value >= $min) && ($value <= $max) && $inc ) {
			return TRUE;
		}
		
		return FALSE;
	}
	
	public static function isCcnum($value, $type = NULL) {	
		$value = self::getDigits($value);
		$length = strlen($value);
		
		if ($length < 13 || $length > 19) {
			return FALSE;
		}
		
		$sum = 0;
		$weight = 2;
		
		for ($i = $length - 2; $i >= 0; $i--) {
			$digit = $weight * $value[$i];
			$sum += floor($digit / 10) + $digit % 10;
			$weight = $weight % 2 + 1;
		}
		
		$mod = (10 - $sum % 10) % 10;
		
		return ($mod == $value[$length - 1]);
	}
	
	public static function isDate($value) {
		list($year, $month, $day) = sscanf($value, '%d-%d-%d');
		
		return checkdate($month, $day, $year);
	}
	
	public static function isDigits($value) {
		return ctype_digit((string) $value);
	}
	
	public static function isEmail($value) {
		return preg_match('/^[-!#$%&\'*+\\.\/0-9=?A-Z^_`{|}~]+@([-0-9A-Z]+\.)+([0-9A-Z]){2,4}$/i', $value);
	}
	
	public static function isName($value) {
		return (bool) !preg_match('/[^[:alpha:]\ \-\']/', $value);
	}
	
	/**
	 * not empty is ok
	 */
	public static function isNormal($value) {
		$value	=	trim($value);
		return ( empty($value) ? false : true );
	}

	public static function isFloat($value) {
		$locale = localeconv();
		
		$value = str_replace($locale['decimal_point'], '.', $value);
		$value = str_replace($locale['thousands_sep'], '', $value);
		
		return (strval(floatval($value)) == $value);
	}
	
	public static function isGreaterThan($value, $min) {
		return ($value > $min);
	}
	
	public static function isHex($value) {
		return ctype_xdigit($value);
	}
	
	public static function isHostname($value, $allow = self::HOST_ALLOW_ALL) {
		if ( !is_numeric($allow) || !is_int($allow) ) {
			throw new Filter_Exception('Illegal value for $allow; expected an integer');
		}
		
		if ($allow < self::HOST_ALLOW_DNS || self::HOST_ALLOW_ALL < $allow) {
			throw new Filter_Exception('Illegal value for $allow; expected integer between ' .
				self::HOST_ALLOW_DNS . ' and ' . self::HOST_ALLOW_ALL);
		}
		
		// determine whether the input is formed as an IP address
		$status = self::isIp($value);
		
		// if the input looks like an IP address
		if ( $status ) {
			// if IP addresses are not allowed, then fail validation
			if ( ($allow & self::HOST_ALLOW_IP) == 0 ) {
				return FALSE;
			}
			
			// IP passed validation
			return TRUE;
		}
		
		// check input against domain name schema
		$status = @preg_match('/^(?:[^\W_](?:[^\W_]|-){0,61}[^\W_]\.)+[a-zA-Z]{2,6}\.?$/', $value);
		if ( $status === false ) {
			throw new Filter_Exception('Internal error: DNS validation failed');
		}
		
		// if the input passes as an Internet domain name, and domain names are allowed, then the hostname
		// passes validation
		if ( $status == 1 && ($allow & self::HOST_ALLOW_DNS) != 0 ) {
			return TRUE;
		}
		
		// if local network names are not allowed, then fail validation
		if ( ($allow & self::HOST_ALLOW_LOCAL) == 0 ) {
			return FALSE;
		}
		
		// check input against local network name schema; last chance to pass validation
		$status = @preg_match('/^(?:[^\W_](?:[^\W_]|-){0,61}[^\W_]\.)*(?:[^\W_](?:[^\W_]|-){0,61}[^\W_])\.?$/',	$value);
		if ( $status === FALSE ) {
			throw new Filter_Exception('Internal error: local network name validation failed');
		}
		
		if ( $status == 0) {
			return FALSE;
		} else {
			return TRUE;
		}
	}
	
	public static function isInt($value) {
		$locale = localeconv();
		
		$value = str_replace($locale['decimal_point'], '.', $value);
		$value = str_replace($locale['thousands_sep'], '', $value);
		
		return (strval(intval($value)) == $value);
	}
	
	public static function isIp($value) {
		return (bool) ip2long($value);
	}
	
	public static function isLessThan($value, $max) {
		return ($value < $max);
	}
	
	public static function isOneOf($value, $allowed = NULL) {
		return in_array($value, $allowed);
	}
	
	public static function isRegex($value, $pattern = NULL) {
		return (bool) preg_match($pattern, $value);
	}

	public static function isUri($value){
		/**
		 * @todo
		 */
	}
	
	public static function isZip($value) {
		return (bool) preg_match('/(^\d{5}$)|(^\d{5}-\d{4}$)/', $value);
	}
	
	public static function noTags($value) {
		return strip_tags($value);
	}
    
	public static function noPath($value) {
		return basename($value);
	}
}
?>